import { Autoplainning } from "Autoplanning/Autoplainning";
import { PathFinderManager } from "GameLoop/Path/PathFinderManager";
import { StationNetwork } from "GameLoop/Path/StationNetwork";
import { NineMineStrategy } from "GameLoop/WorldState/EntityManager/CreateStrategy/NineMineStrategy";
import { CacheBlueplan } from "GameLoop/WorldState/PollingStation/PollingTasks/RoomItem/CacheBlueplan";
import { priority } from "utils/constants/definetypes";
import { PositionHelper } from "utils/position/PositionHelper";
import { UtilsHelper } from "utils/position/UtilsHelper";
import {VisualHelper} from "utils/visual/visual";
 

export default 
{
     
    test:{
        updateTask()
        {
            for(const e in Game.rooms)
            {
                const room = Game.rooms[e];
                if(room.getType() ==1)
                {
                    room.getTaskByType("creep")
                    room.getTaskByType("creep").forEach(e=>
                        {
                            e.data.required.forEach(item=>
                                item[2]=item[1])
                        })
                    room.getTaskByType("team").forEach(e=>
                        {
                            e.data.creepRequired.forEach(item=>
                                item[2]=item[1])
                        })
                }
            }


        },
        towerTask(room:string)
        {
            const repairTask:IRoomTaskData<"towerRepair"> = 
            {
                type: "towerRepair",
                arg: {
                    room: room,
                    targets: {}
                }
            }
            const code:IDecisionCode<"tower">={
                region:room,
                isunique:false,
                task:[{
                    id:`${room}_tower_repair`,
                    ttl:5000,
                    priority:priority.D,
                    type:"tower",
                    data:repairTask,
                    shard:0,
                }  ],
            }
            global.addTask(code.task[0],room);
            // Game.rooms[room].addNewTask(code.task[0]);
        },
        clearSpawnTask()
        {
            for(const e in Game.rooms)
            {
                const room = Game.rooms[e];
                if(room.getType() ==1)
                {
                    room.getEntity("SpawnEntity").spawnQueue.clear()
                }
            }
        },
        updateCenterRoom(roomName:string)
        {
            NineMineStrategy.check(Game.rooms[roomName],global.entityDB);
        },
        removeEntity(guid:string)
        {
            // test.removeEntity("xcSd6174");
            return global.entityDB.removeEntityByID(guid);
        },
        /**
         * 移除外矿实体
         * @param roomName 
         * @param mineRoom 
         */
        removeRemoteMine(roomName:string,mineRoom:string)
        {
            // roomName="E3S34";
            // mineRoom = "E5S34";
            
            let entitys =global.entityDB.getEntitys("OutMineEntity",roomName);
            const entitys2 =global.entityDB.getEntitys("OutMinerialEntity",roomName);
            entitys = entitys.concat(entitys2 as any );
            for(const e of entitys)
            {
                if(e.roomName == mineRoom)
                {
                    global.entityDB.removeEntityByID(e.GUID());
                    
                }
            }
            Game.rooms[roomName].getTaskByType("creep",e=>e.data.room == mineRoom).forEach(e=>
                {
                    Game.rooms[roomName].deleteTaskById(e.id);
                })
            Memory.rooms[mineRoom]={} as any;
        },
        avoidRoom(room:string[],time=-1)
        {
             // test.avoidRoom(["E54S42" ],30000);
             // test.avoidRoom(["E49S19","E49S17","E48S17","E49S18"],50000);
            room.forEach(e=>StationNetwork.getInstance.addAvoidRoom(e,time));
        },
        pathCost(room:string,decorate = ["c_structure","c_creep","c_position"])
        {
            StationNetwork.getInstance.PathFinder.visualDebugCost(Game.rooms[room],decorate as any,{})
        },
        visualRoomCost(room:string)
        {
            const cache = global.world.PollBlueplan(room);
            if(cache)
            {
                VisualHelper.drawMatrix(Game.rooms[room],cache.getMatrix());
                
            }
            // const keys = Object.keys(Memory.Data.station._normal_paths);
            // for(let k of keys)
            // {
            //     if(k.includes("E52S22"))
            //     {
            //         delete Memory.Data.station._normal_paths[k];
            //     }
            // }
            // Game.rooms["E57S54"].find(FIND_STRUCTURES,{filter:{type:STRUCTURE_ROAD}}).filter(e=>e.structureType == STRUCTURE_ROAD  && e.pos.x>38 && e.pos.y>29).forEach(p=>p.destroy());
            // Game.rooms["E57S54"].find(FIND_STRUCTURES ).filter(e=>e.structureType == STRUCTURE_ROAD &&  e.pos.x>38 && e.pos.y>29).forEach(p=>p.destroy());
        },
        visualRoad(room:string,isdestory=false)
        {
            const plans = (Game.rooms[room].getWorld().PollBlueplan(room) as CacheBlueplan).getNormalPlan()
            const allroad = plans.SiteQueue.items.filter(e=>e.type == STRUCTURE_ROAD) ;                  
            Game.rooms[room].find(FIND_STRUCTURES,{filter: { structureType: STRUCTURE_ROAD }}).filter(
                e=>
                {
                    if(StationNetwork.getInstance.PathCache.isStandPath(e.pos))
                    {
                        return false;
                    }
                    if(allroad.find(p=>e.pos.x == p.pos.x && e.pos.y == p.pos.y))
                    {
                        return false
                    }
                    return true
                }
            ).forEach(s=>
                {
                    Game.rooms[room].visual.text('O',s.pos);
                    if(isdestory)
                    {
                        s.destroy()
                    }
                })
        },
        visualRoomStructureCost(room:string)
        {
            const cache = global.world.PollStructure(room);
            if(cache)
            {
                VisualHelper.drawMatrix(Game.rooms[room],cache.getCostMatrix());
                
            }
        },
        visualRoomPlan(room:string)
        {
           
            const cache = global.world.PollBlueplan(room);
            if(cache)
            {
                VisualHelper.drawRoom(Game.rooms[room],cache.getNormalPlan().SiteQueue);
            }
        },
        visualPathByKey(key:string)
        {
           
            const path = StationNetwork.getInstance.getPathByKey(key);
            if(path)
            {
                VisualHelper.drawPath( path);
                Memory.Debug['visualPathByKey'] = path;
            }
        },
        pathtest(A:IRoomPosition={x:17,y:28,roomName:"W7N9"},B:IRoomPosition={x:16,y:44,roomName:"W7N9"})
        {
            // const keys = Object.keys(Game.constructionSites);
            // keys.forEach(v=> 
            // {
            //     if(Game.constructionSites[v].structureType=="road")
            //     {
            //         Game.constructionSites[v].remove();
            //     }
            // })
            // const path = Room.serializePath(Game.rooms["E53S44"].findPath(new RoomPosition(17,23,"E53S44"),new RoomPosition(17,25,"E53S44")));

            // pathcache.PathCache.findPathCache(new RoomPosition(18,48,"E53S57"),new RoomPosition(18,27,"E53S58"),true);
            const target = PositionHelper.Create(B);
            const origin = PositionHelper.Create(A);
            //const paths = StationNetwork.getInstance.searchRoad(origin,{pos:target,range:0},{});

            // Memory.Debug['pathtest'] = paths;
            // if(paths)
            // {
            //     const cache =  UtilsHelper.serializePathResult(origin,paths);
            //     Memory.Debug['pathtest2']=cache;
            //     Memory.Debug['pathtest3']=UtilsHelper.deserializePathCache(
            //         {
            //             pos:UtilsHelper.serializePos(origin),
            //             cache:cache.cache
            //         } );
            // }
            const rets = StationNetwork.getInstance.PathCache.findPathCache(origin,target);
            if(rets)
            {
                const paths = UtilsHelper.deserializePathCache({ pos:UtilsHelper.serializePos(origin),
                cache:rets.value});
                // VisualHelper.drawPath( paths);
                Game.rooms[paths[0].roomName].visual.poly(paths, { stroke: 'red', lineStyle: 'dashed', strokeWidth: 0.15 });
                return paths;
            }
            return 
            // StationNetwork.getInstance.PathCache.findPathCache(new RoomPosition(18,48,"E53S57"),new RoomPosition(18,27,"E53S58"),true);
        },
        updateNine()
        {
            for(let k in Game.rooms)
            {
                if(Game.rooms[k].getType() == 6)
                {
                    NineMineStrategy.check(Game.rooms[k],global.entityDB);
                }
            }
            
        },
        visualMinePath(roomName:string)
        {
            const room = Game.rooms[roomName];
            
            const innerMine = room.getEntitys("InnerMineEntity");
            const outMine = room.getEntitys("OutMineEntity");
       
            for(const e of innerMine)
            {
               // e.getNodeMemory().path =undefined as any;
                if(e.getNodeMemory().pathkey)
                {
                    const paths = StationNetwork.getInstance.getPathByKey(e.getNodeMemory().pathkey);
                    if(paths)
                    {
                        room.visual.poly(paths.filter(e=>e.roomName == roomName))
                    }
                    
                }
              
            }
            for(const e of outMine)
            {
                // e.getNodeMemory().path =undefined as any;
                if(e.getNodeMemory().pathkey)
                {
                    const paths = StationNetwork.getInstance.getPathByKey(e.getNodeMemory().pathkey);
                    if(paths)
                    {
                        room.visual.poly(paths.filter(e=>e.roomName == roomName))
                    }
                }
            }
        },
        removeMinePath(roomName?:string)
        {
            // for(let k in Memory.rooms)
            // {
            //     const roommem  = Memory.rooms[k];
            //     if(roommem.config.type ==1)
            //     {
            //         for(let n in roommem.Nodes)
            //         {
            //             const node = roommem.Nodes[n];
            //             node.pathkey = undefined;
            //         }
            //     }
            // }
            const removeMinePath = (room:Room)=>
            {
                const innerMine = room.getEntitys("InnerMineEntity");
                const outMine = room.getEntitys("OutMineEntity");
                const Minerial = room.getEntitys("MinerialEntity");
                for(const e of innerMine)
                {
                   // e.getNodeMemory().path =undefined as any;
                    if(e.getNodeMemory().pathkey)
                    {
                        StationNetwork.getInstance.clearPath(e.getNodeMemory().pathkey)
                    }
                  
                }
                for(const e of outMine)
                {
                    // e.getNodeMemory().path =undefined as any;
                    if(e.getNodeMemory().pathkey)
                    {
                        StationNetwork.getInstance.clearPath(e.getNodeMemory().pathkey)
                    }
                }
                for(const e of Minerial)
                {
                    if(e.getNodeMemory().pathkey)
                    {
                        StationNetwork.getInstance.clearPath(e.getNodeMemory().pathkey)
                    }
                }
            }
            if(roomName)
            {
                const room = Game.rooms[roomName];
                if(room)
                {
                    removeMinePath(room);
                }else
                {
                    throw new Error(`${roomName} 房间没有视野`);
                }
            }
            else 
            {
                for(let r in Game.rooms)
                {
                    if(Game.rooms[r].IsMy())
                    {
                        removeMinePath(Game.rooms[r]);
                    }
                }
            }
            
        },
        triggerLevelUp(roomName:string)
        {
            const room = Game.rooms[roomName];
            global.triggerEvent(room.name,"LevelUp",{
                region:room.memory.lord,
                room:room.name,                
            })
        },
        war(myroom:string,roomName:string, benchRooms:[])
        {
            //  测试战争任务
            const bodyitem:BodyItem=[[RANGED_ATTACK,2],[HEAL,2],[MOVE,2]];
            const wartask:ITeamTaskData<"defend">  ={
                type: "defend",
                room: roomName,
                arg: {
                    benchRooms:benchRooms,
                    enemy: [],
                    structures: [],
                },
                creeps: [],
                teams: {} as any,
                creepRequired: [
                    [
                        {
                            Role: "idaBlue",
                            body: bodyitem,
                            boost: 3,
                        },
                        1
                    ]
                ],
                required: [],
                cost: 0
            }
            const teamTask:ITaskDeclare["team"]=
            {
                id:`${roomName}_war`,
                priority: priority.A,
                ttl: 5000,
                type: "team",
                data: wartask,
                shard: 0
            }
            Game.rooms[myroom].addNewTask(teamTask);
            return teamTask;
        },
        warTeam2(myroom:string,roomName:string)
        {
            // test.warTeam2("W5N8","W5N8")
            const team2Config:ITeamConfig={
                type:"Team2",
                creep:[
                    [
                        {
                            Role:"idaBlue",
                            
                            body:[[RANGED_ATTACK,4], [HEAL,1],[MOVE,5]]
    
                        },
                        1
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[[RANGED_ATTACK,1],  [HEAL,4],[MOVE,5]]
                        },
                        1
                    ],
                ]
            };
            (global as any).war.attack(myroom,roomName,team2Config)
        },
        warTeam2_A(myroom:string,roomName:string)
        {
            // test.warTeam2_A("E48S15","E52S22")
            /**
             * war.attack("E55S2","E53S1",{
                type:"Team2",
                creep:[
                    [
                        {
                            Role:"idaRed",
                            
                            body:[ [MOVE,25],[ATTACK,20],[RANGED_ATTACK,5]]
    
                        },
                        1
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[  [MOVE,14], [HEAL,25],[MOVE,11]]
                        },
                        1
                    ],
                ]
            })
             */
            const team2Config2:ITeamConfig={
                type:"Team2",
                creep:[
                    [
                        {
                            Role:"idaRed",
                            
                            body:[ [TOUGH,5],[ATTACK,28],[MOVE,17]],
                            boost:2,
    
                        },
                        1
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[  [TOUGH,5], [HEAL,28],[MOVE,17]],
                            boost:2,
                        },
                        1
                    ],
                ]
            };
            /**
             * Game.rooms["E5S33"].getTaskById("E3S34_war").data.required[0]={
                type:"Team4",
                creep:[
                    [
                        {
                            Role:"idaRed",
                            
                            body:[ [TOUGH,5],[ATTACK,28],[MOVE,17]],
                            boost:2,
    
                        },
                        2
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[  [TOUGH,5], [HEAL,28],[MOVE,17]],
                            boost:2,
                        },
                        2
                    ],
                ]
            }
             * war.attack("E5S33","E3S34",{
                type:"Team2",
                creep:[
                    [
                        {
                            Role:"idaRed",
                            
                            body:[ [TOUGH,5],[ATTACK,28],[MOVE,17]],
                            boost:2,
    
                        },
                        1
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[  [TOUGH,5], [HEAL,28],[MOVE,17]],
                            boost:2,
                        },
                        1
                    ],
                ]
            })
             */
            const team2Config:ITeamConfig={
                type:"Team2",
                creep:[
                    [
                        {
                            Role:"idaRed",
                            
                            body:[ [MOVE,25],[ATTACK,20],[RANGED_ATTACK,5]]
    
                        },
                        1
                    ],
                    [
                        {
                            Role:"idaHeal",
                            
                            body:[  [MOVE,14], [HEAL,25],[MOVE,11]]
                        },
                        1
                    ],
                ]
            };
            (global as any).war.attack(myroom,roomName,team2Config)
        },
        warTeam9(myroom:string,roomName:string)
        {
            // test.warTeam9("W5N8","W5N8")
            const team2Config:ITeamConfig={
                type:"Team9",
                creep:[
                    [
                        {
                            Role:"idaBlue",
                            
                            body:[[RANGED_ATTACK,8], [HEAL,2],[MOVE,10]]
    
                        },
                        9
                    ],
                    
                ]
            };
            (global as any).war.attack(myroom,roomName,team2Config)
        },
        warCreep(myroom:string,roomName:string)
        {
             // test.warCreep("E52S52","E53S52")
             // test.warCreep("W7N4","W8N5")
            // const config:IBodyConfig={
            //     Role:"idaRed",
                
            //     body:[[MOVE,22],[ATTACK,18],[HEAL,5],[MOVE,1]]
            // }
             {
                
                //  war.attackByPlan("E52S52","E44S47",{ creep:[[
                //     {
                //         Role:"idaRed",
                        
                //         body:[[MOVE,15],[ATTACK,15],[HEAL,1],[MOVE,1]],
                //         isAdapt:true,
                //     },1]],
                //     team:[]});

                // war.attackByPlan("E57S54","E58S56",{ creep:[],
                //     team:[[
                //         {
                //             type:"Team2",
                //             creep:[
                //                 [
                //                     {
                //                         Role:"idaRed",
                //                         body:[ [MOVE,10],[ATTACK,9],[RANGED_ATTACK,1]]
                //                     },
                //                     1
                //                 ],
                //                 [
                //                     {
                //                         Role:"idaHeal",
                //                         body:[  [MOVE,6], [HEAL,6]]
                //                     },
                //                     1
                //                 ],
                //             ]
                //         }
                //         ,1
                //     ]]},
                //     ["E58S56","E58S59","E56S59","E55S59"]);
            }
            const plan:IWarPlan={ creep:[[
                {
                    Role:"idaBlue",
                    
                    body:[[MOVE,5],[RANGED_ATTACK,5],[HEAL,1],[MOVE,1]]
                },1]],
                team:[]};
            (global as any).war.attackByPlan(myroom,roomName,plan);
        },
        getTerrain(roomName:string)
        {
           
            return Autoplainning.GetTerrainBuffer(roomName)
        },
        getPathCache()
        {
            // test.getPathCache().findPathCache(new RoomPosition(10,38,"W2N5"),new RoomPosition(11,26,"W2N5"))
            return StationNetwork.getInstance.PathCache
        },
        getStationNetwork()
        {
            
            // test.getStationNetwork().PathFinder._blockCreeps
            return StationNetwork.getInstance
        }
    },
 
}